﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using System.Threading;
using System.Threading.Tasks;
using Api;
using Customer.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.WebEncoders;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using ServiceCore.Token;
using ServiceCore.Tool;
using ServiceCore.Tool.AliFace;
using ServiceCore.Tool.Barcode;
using ServiceCore.Tool.Dapper;
using ServiceCore.Tool.ES;
using ServiceCore.Tool.JD_Pay;
using ServiceCore.Tool.MiniProgram;
using ServiceCore.Tool.MongoDB;
using ServiceCore.Tool.Mqtt;
using ServiceCore.Tool.NPOI;
using ServiceCore.Tool.Pic;
using ServiceCore.Tool.Quartz;
using ServiceCore.Tool.Text;
using ServiceCore.Tool.TIM;
using ServiceCore.Tool.Wx.customservice;
using ServiceCore.Tool.Wx.diy_menu;
using ServiceCore.Tool.Wx.media;
using Swashbuckle.AspNetCore.Swagger;

namespace Customer
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit = 60000000;
            });
            services.Configure<WebEncoderOptions>(options =>
                     options.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.BasicLatin,
                     UnicodeRanges.CjkUnifiedIdeographs));
            services.AddMvc(opt =>
            {
                //在各个控制器添加前缀（没有特定的路由前面添加前缀）
                opt.UseCentralRoutePrefix(new RouteAttribute("/[controller]/[action]"), Configuration);
                //opt.UseCentralRoutePrefix(new RouteAttribute("api/[controller]/[action]"));  
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddJsonOptions(option =>
            {
                option.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                //option.SerializerSettings.ContractResolver = new DefaultContractResolver();
            });
            services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //注入http上下文
            services.AddSingleton<IDapper_Helper, Dapper_Helper>(); //注入dapper的通用使用方法
            services.AddSingleton<ISnowflake_Helper, Snowflake_Helper>();//注入ID生成方法
            services.AddSingleton<ITokenUser_Service, TokenUser_Service>();//注入ID生成方法   
            services.AddSingleton<ICacheHelper, MemoryCacheHelper>();//注入cache方法 
            services.AddSingleton<IEs_Log_Helper, Es_Log_Helper>();//注入Es方法  
            services.AddSingleton<IEs_Log_HelperForQA, Es_Log_HelperForQA>();//注入Es方法   
            services.AddSingleton<IMongoDB_Config, MongoDB_Config>();//注入mongo连接配置
            services.AddSingleton(typeof(IMongoDB_Client<>), typeof(MongoDB_Client<>));//注入mongo连接方法  
            services.AddSingleton<IEMQ_Helper, EMQ_Helper>();//注入MQTT连接 
            services.AddSingleton<IRK_Mqtt, RK_Mqtt>();//注入RK_Mqtt连接 
            services.AddSingleton<IEmqMongo_Service, EmqMongo_Service>(); //注入EMP需要的操作mongo方法
            services.AddSingleton<IUpload_Helper, Upload_Helper>(); //注入图片上传时方法 
            services.AddSingleton<IJD_API, JD_API>();///注入京东支付相关方法
            services.AddSingleton<IMiniProgramApi, MiniProgramApi>();///注入京东支付相关方法
            services.AddSingleton<IRW_Helper, RW_Helper>();///注入模板 
            services.AddSingleton<IMchType_Helper, MchType_Helper>();//注入机器类型方法   
            services.AddSingleton<IBarcode_Service, Barcode_Service>();//注入条码生成
            services.AddSingleton<INpoi_service, Npoi_service>();//注入excel相关方法
            services.AddSingleton<IAnalyzer_jieba, Analyzer_jieba>(); ///注入分词方法
            //services.AddScoped<Filter.Api_Filter>(); //注入接口验证  
            services.AddSingleton<IEs_knowledge, Es_knowledge>(); ///注入知识库相关
            services.AddSingleton<Ies_cloud_product, es_cloud_product>(); ///注入云商品库相关

            services.AddSingleton<IFacePay, FacePay>(); ///注入云商品库相关
              
            services.AddSingleton<Icustom_service, custom_service>(); ///注入微信客服系统相关接口
            services.AddSingleton<Idiy_menu_service, diy_menu_service>(); ///注入自定义菜单相关接口 
            services.AddSingleton<Iwx_media_service, wx_media_service>(); ///注入微信素材库相关接口  

            //注入 Quartz调度类
            services.AddSingleton<QuartzStartup>();
            services.AddTransient<check_aliface>();      // 这里使用瞬时依赖注入 
            services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();//注册ISchedulerFactory的实例。   
            services.AddSingleton<IJobFactory, IOCJobFactory>();

            //注入腾讯IM相关接口方法
            services.AddSingleton<Itim_service, tim_service>();

            #region 开始注册业务  
            Api.DI.Run_Service.DI_Run(Configuration, services);//注入方法集   
            #endregion  
            //注入cores
            services.AddCors(options =>
            {
                options.AddPolicy("AllowSpecificOrigin",
                    builder =>
                    {
                        builder.WithOrigins("*").WithMethods("*").WithHeaders("token", "Content-Type", "Id", "BaseUserId", "token", "authorization", "accept");
                        //builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
                    });
            });
            //注册Swagger生成器，定义一个和多个Swagger 文档
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info { Title = "睿科售后", Version = "v1", Description = Configuration["Swagger:des"] });
                options.OperationFilter<Api.Swagger.AddAuthTokenHeaderParameter>();
                //var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.XML";
                //var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                //options.IncludeXmlComments(xmlPath);
                //var xmlPathEng = Path.Combine(AppContext.BaseDirectory, "Entity.xml");
                //options.IncludeXmlComments(xmlPathEng); 
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IRK_Mqtt rkMqtt, INpoi_service npoi,IApplicationLifetime appLifetime)
        { 
            npoi.StartClearExcel(); 
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //启用中间件服务对swagger-ui，指定Swagger JSON终结点
                app.UseSwaggerUI(c =>
                {
                    c.ShowExtensions();
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "睿科售后 V1");
                    c.InjectJavascript("/Script/jquery-1.10.2.min.js");
                    c.InjectJavascript("/Script/swagger_cn.js");
                });
                //启用中间件服务生成Swagger作为JSON终结点
                app.UseSwagger();
            }
            else
            {
                //获取前面注入的Quartz调度类
                var quartz = app.ApplicationServices.GetRequiredService<QuartzStartup>();

                appLifetime.ApplicationStarted.Register(() =>
                {
                    quartz.Start().Wait(); //网站启动完成执行
                });
                appLifetime.ApplicationStopped.Register(() =>
                {
                    quartz.Stop();  //网站停止完成执行

                });

                app.UseHsts();
                //启用中间件服务对swagger-ui，指定Swagger JSON终结点
                app.UseSwaggerUI(c =>
                {
                    c.ShowExtensions();
                    c.SwaggerEndpoint("/Customer/swagger/v1/swagger.json", "睿科售后 V1");
                    c.InjectJavascript("/Customer/Script/jquery-1.10.2.min.js");
                    c.InjectJavascript("/Customer/Script/swagger_cn.js");
                });
                //启用中间件服务生成Swagger作为JSON终结点
                app.UseSwagger(c =>
                {
                    c.PreSerializeFilters.Add((swagger, httpReq) =>
                    {
                        swagger.BasePath = "/Customer";
                    });
                });
            }
            ////启动websocket
            //var webSocketOptions = new WebSocketOptions()
            //{
            //    KeepAliveInterval = TimeSpan.FromSeconds(60),
            //    ReceiveBufferSize = 4 * 1024
            //};
            //app.UseWebSockets();
            //app.UseMiddleware<WebSocketMiddleware>();


            //app.UseHttpsRedirection();
            app.UseMvc();
            app.UseStaticFiles();
            app.UseCustomErrorPages(); 
            //使用注入规则
            app.UseCors("AllowSpecificOrigin");
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                  name: "areas",
                  template: "{area:exists}/{controller}/{action}/{id?}",
                   defaults: new { area = "System", controller = "Home", action = "Index" }
                );
            }); 
        }
    }
}
